/*
 *
 * Copyright (c) 2009-2010 Capgemini Greater China - FS GBU
 * 24th Floor, Asia Plaza, No. 18 Zhao Feng Road, Huaqiao, Kunshan, P.R.C.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Capgemini. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Capgemini.
 */

package com.capgemini.fs.presentation.role.web.action;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import java.util.*;

import com.capgemini.fs.app.ekms.common.Constants;
import com.capgemini.fs.app.ekms.model.Role;
import com.capgemini.fs.app.ekms.model.Functionality;

import com.capgemini.fs.app.ekms.service.RoleService;
import com.capgemini.fs.app.ekms.service.FunctionalityService;
import com.capgemini.fs.app.ekms.service.UserService;

import com.capgemini.fs.presentation.role.web.form.RoleNameForm;
import com.capgemini.fs.presentation.role.web.form.MaintainRoleForm;

import net.sf.json.JSONObject;

/**
 * MaintainRoleAction Class
 * 
 * 
 * @version 1.0
 * @author Jack
 * 
 */
public class MaintainRoleAction extends DispatchAction {
	private RoleService roleService;

	private FunctionalityService functionalityService;

	private UserService userService;
	
	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public FunctionalityService getFunctionalityService() {
		return functionalityService;
	}

	public void setFunctionalityService(
			FunctionalityService functionalityService) {
		this.functionalityService = functionalityService;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	/**
	 * Load role information when action type is load
	 * 
	 * @throws Exception
	 */
	public ActionForward load(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		try {
			HttpSession session = request.getSession();
			String username = session.getAttribute("username").toString();
			Set<Role> roleSet = userService.getUserByName(username).getRoles();
			
			Iterator<Role> roleSetIterator = roleSet.iterator();
			
			int i = 0;
			Boolean adminRole;
			while(roleSetIterator.hasNext()){
			     Role e = roleSetIterator.next();
			     if(e.getName().toLowerCase().equals("admin")){
			    	 i++;
			     }
			}
			if(i>0){
				adminRole = true;
			}else{
				adminRole = false;
			}
			
			/* Get all roles */
			List<Role> roleList = roleService.getAllRoles();

			Vector<RoleNameForm> entries = new Vector<RoleNameForm>(1);
			for (Role role : roleList) {
				if(!adminRole && role.getName().toLowerCase().equals("admin")){
					continue;
				}
				entries.add(new RoleNameForm(role.getName(), role.getId()
						.toString()));
			}
			MaintainRoleForm maintainRoleForm = new MaintainRoleForm();
			/* Set all roles to BeanCollection for dropdown list in page */
			maintainRoleForm.setBeanCollection(entries);

			/* Get all functionalities */
			List<Functionality> functionalityList = functionalityService
					.getAllFunctionalities();

			/* Get functionality category */
			List<String> categoryList = functionalityService
					.getAllFunctionalityCategories();

			maintainRoleForm.setCategoryList(categoryList);
			maintainRoleForm.setFunctionalityList(functionalityList);

			/* Return maintainRoleForm to page */
			request.setAttribute("maintainRoleForm", maintainRoleForm);

			return mapping.findForward("succ");
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * Update role information when action type is updateFunctionality
	 * 
	 * @throws Exception
	 */
	public ActionForward updateFunctionality(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		/* Initialize JSON */
		String jsonString = readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);

		/* SerializeR Role object */
		Role role = serializeRole(jot);

		MaintainRoleForm maintainRoleForm = (MaintainRoleForm) form;
		try {
			/* Get all roles */
			List<Role> roleList = roleService.getAllRoles();

			Vector<RoleNameForm> entries = new Vector<RoleNameForm>(1);
			for (Role r : roleList) {
				entries.add(new RoleNameForm(r.getName(), r.getId()
						.toString()));
			}

			/* Set all roles to BeanCollection for dropdown list in page */
			maintainRoleForm.setBeanCollection(entries);

			/* Get all functionalities */
			List<Functionality> functionalityList = functionalityService
					.getAllFunctionalities();
			/* Get functionality category */
			List<String> categoryList = functionalityService
					.getAllFunctionalityCategories();

			maintainRoleForm.setCategoryList(categoryList);
			maintainRoleForm.setFunctionalityList(functionalityList);

			/* Get Selected Functionality */
			Integer roleID = role.getId(); // get selected roleID from page
			Set<Functionality> functionalitySet = roleService.getRoleById(
					roleID).getFunctionalities();
			ArrayList<Functionality> selectedFunctionalityList = new ArrayList<Functionality>();
			selectedFunctionalityList.addAll(functionalitySet);
			maintainRoleForm
					.setSelectedFunctionalityList(selectedFunctionalityList);

			/* Return maintainRoleForm to page */
			request.setAttribute("maintainRoleForm", maintainRoleForm);

			/* Set role status */
			if (roleService.getRoleById(roleID).getStatus().equals(
					Constants.ROLE_STATUS_ACTIVE)) {
				maintainRoleForm.setRoleActive("Yes"); // Active Role
			} else if (roleService.getRoleById(roleID).getStatus().equals(
					Constants.ROLE_STATUS_INACTIVE)) {
				maintainRoleForm.setRoleActive("No"); // Inactive Role
			}

			/* Return JSON object to page */
			try {
				PrintWriter out = response.getWriter();
				JSONObject jsonObject = new JSONObject();
				JSONObject jso = new JSONObject();
				jso.put("maintainRoleForm", maintainRoleForm);
				jsonObject.put("notice", "Modified Successfully!");
				jsonObject.put("role", jso);
				out.print(jsonObject);
				out.flush();
				out.close();
				return null;
			} catch (Exception exc) {
				exc.printStackTrace();
				throw exc;
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * Update role information
	 * 
	 * @throws Exception
	 */
	public ActionForward update(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		try {
			/* Get Session */
			HttpSession session = request.getSession();

			MaintainRoleForm maintainRoleForm = (MaintainRoleForm) form;

			/* Get role information by role id */
			Role role = roleService.getRoleById(Integer
					.parseInt(maintainRoleForm.getRoleId()));

			role.setName(maintainRoleForm.getRole_name());
			role.setLastModifier(session.getAttribute("username").toString());
			role.setLastUpdateDate(new Date());

			/* Set role status */
			if (maintainRoleForm.getRoleActive().equals("Yes")) {
				role.setStatus(Constants.ROLE_STATUS_ACTIVE); // Active role
			} else if (maintainRoleForm.getRoleActive().equals("No")) {
				role.setStatus(Constants.ROLE_STATUS_INACTIVE); // Inactive role
			}

			/* Construct FunctionalityList */
			Set<Functionality> functionalityListForInsert = new HashSet<Functionality>();

			/* Get functionalities from page */
			String[] selectedFunctionList = maintainRoleForm
					.getFunctionCheckBox();
			if (selectedFunctionList != null) {
				for (int i = 0; i < selectedFunctionList.length; i++) {
					Functionality functionality = functionalityService
							.getFunctionalityByFunctionalityCode(selectedFunctionList[i]);
					functionalityListForInsert.add(functionality);
				}
			}
			role.setFunctionalities(functionalityListForInsert);

			/* Update role information */
			roleService.updateRole(role);

			/* Get latest roles */
			List<Role> roleList = roleService.getAllRoles();

			Vector<RoleNameForm> entries = new Vector<RoleNameForm>(1);
			for (Role r : roleList) {
				entries.add(new RoleNameForm(r.getName(), r.getId()
						.toString()));
			}
			maintainRoleForm.setBeanCollection(entries);

			/* Return maintainRoleForm to page */
			request.setAttribute("maintainRoleForm", maintainRoleForm);

			/* Set success notice to page */
			request.setAttribute("Success", "Saved Successfully!");
			return mapping.findForward("succ");
		} catch (Exception e) {
			// throw e;
			e.printStackTrace();
			return mapping.findForward("failed");
		}
	}
	
	/**
	 * Update role information
	 * 
	 * @throws Exception
	 */
	public ActionForward checkCurrentRole(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		/* Initialize JSON */
		String jsonString = readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);
		
		String roleName = jot.getString("roleName");
		
		/* Get Session */
		HttpSession session = request.getSession();
		
		Set<Role> roleSet = userService.getUserByName(session.getAttribute("username").toString()).getRoles();
		
		Iterator<Role> roleSetIterator = roleSet.iterator();

		int i = 0;
		String allow;
		while(roleSetIterator.hasNext()){
		     Role e = roleSetIterator.next();
		     if(roleName.equals(e.getName())){
		    	 i++;
		     }
		}
		if(i>0){
			allow = "False";
		}else{
			allow = "True";
		}
		
		/* Return JSON object to page */
		try {
			PrintWriter out = response.getWriter();
			JSONObject jsonObject = new JSONObject();
			JSONObject jso = new JSONObject();
			jso.put("allow", allow);
			jsonObject.put("notice", "Modified Successfully!");
			jsonObject.put("role", jso);
			out.print(jsonObject);
			out.flush();
			out.close();
			return null;
		} catch (Exception exc) {
			exc.printStackTrace();
			throw exc;
		}
	}

	/**
	 * Read JSON By Request
	 * 
	 * @throws IOException
	 */
	private String readJSONRequest(HttpServletRequest request)
			throws IOException {
		StringBuffer sb = new StringBuffer();
		String line;
		try {
			BufferedReader reader = request.getReader();
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
		return sb.toString();
	}

	/**
	 * serialize a Group from JSONObject
	 * 
	 */
	public Role serializeRole(JSONObject jo) {
		Role role = new Role();

		role.setId(jo.getInt("id"));

		role.setName(jo.getString("roleName"));
		return role;
	}

	/**
	 * Check Role Name Exist
	 * 
	 * @throws Exception
	 */
	public ActionForward checkRoleName(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		String jsonString = readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);
		Role role = serializeRole(jot);
		String roleNameExist;

		/*Whether the role name after change is the same as selected role name*/
		if (roleService.getRoleById(role.getId()).getName()
				.toLowerCase().equals(role.getName().toLowerCase())) {	//role name is the same
			roleNameExist = "No";
		} else {	//role name is not the same
			/*Whether the role name exists in the system*/
			if (roleService.getRoleByName(role.getName()) != null) {	//role name does not exist
				roleNameExist = "Yes";
			} else {	//role name exists
				roleNameExist = "No";
			}
		}

		/*Return JSON object to page*/
		try {
			PrintWriter out = response.getWriter();
			JSONObject jsonObject = new JSONObject();
			JSONObject jso = new JSONObject();
			jso.put("roleNameExist", roleNameExist);
			jsonObject.put("notice", "Modified Successfully!");
			jsonObject.put("role", jso);
			out.print(jsonObject);
			out.flush();
			out.close();
			return null;
		} catch (Exception exc) {
			exc.printStackTrace();
			throw exc;
		}
	}
}
